package com.samehope.ar.handler;

import com.samehope.ar.common.CommonResult;
import com.samehope.ar.common.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @Description:
 * @Author: ZhangLuo
 * @Email: zhangluo@iworkgo.com
 * @Date: 2019-10-22 11:33
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 业务异常
     * @param e
     * @return
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public CommonResult serviceExceptionHandler(IllegalArgumentException e) {
        log.error("业务异常: {}", e.getMessage(), e);
        return CommonResult.validFailed(e.getMessage());
    }

    /**
     * 请求参数绑定失败异常
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public CommonResult bindException(BindException e) {
        log.error("参数绑定异常: {}", e.getMessage(), e);
        return CommonResult.validFailed(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }

    /**
     * 请求方法使用错误异常
     * @param e
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public CommonResult httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        return CommonResult.validFailed("请求方法错误, 请查阅接口文档");
    }

    /**
     * 缺少请求参数
     * @param e
     * @return
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public CommonResult httpMessageNotReadableException(HttpMessageNotReadableException e) {
        e.printStackTrace();
        return CommonResult.validFailed("请求参数缺失, 请求体是必须的");
    }

    /**
     * 参数校验失败
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public CommonResult MethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("参数校验失败: {}", e.getMessage(), e);
        return CommonResult.validFailed(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }

    /**
     * 鉴权失败异常处理
     * @return
     */
    @ExceptionHandler(AccessDeniedException.class)
    public CommonResult accessDeniedException() {
        return CommonResult.failed(ResultCode.FORBIDDEN);
    }

    /**
     * 未知异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public CommonResult exception(Exception e) {
        e.printStackTrace();
        return CommonResult.failed(e.getMessage());
    }
}
